package bakaserver.recipe;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.plugin.java.JavaPlugin;

import net.elseland.xikage.MythicMobs.MythicMobs;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.CraftItemEvent;

public final class recipe extends JavaPlugin implements Listener {
	public final int REC_LINE1 = 0, REC_LINE2 = 1, REC_LINE3 = 2, REC_RESULT = 3, REC_PERM = 5, REC_RESULT_COUNT = 4;
	public static Logger consoleLogger;
	public YamlConfiguration yamlConfig;
	public static boolean debug;
	public File cfg;
	public Map<Integer, RecipeItem> rec = new HashMap<Integer, RecipeItem>();
	public Map<Integer, ShapedRecipe> sr = new HashMap<Integer, ShapedRecipe>();
	public int itemCount;
	public boolean enablePerm;
	public static MythicMobs mmMobsInstance = null;
	ShapedRecipe GetRecipe(ItemStack target, String[] source) {
		ShapedRecipe sr = new ShapedRecipe(target);

		char f = 'a';
		String t = "";
		List<String> chrRecipe = new ArrayList<String>();
		Map<String, String> itemRecipe = new HashMap<String, String>();
		for (int c = 0; c < 3; c++) {
			for (String p : source[c].split(",")) {
				String id;
				if (p.contains(":")) {
					id = p.split(":")[0];
				} else {
					id = p;
				}
				if (Integer.parseInt(id) > 0) {
					t += String.valueOf(f);
					if (!itemRecipe.containsKey(String.valueOf(f))) {
						itemRecipe.put(String.valueOf(f), p);
						f++;
					}
				}
			}
			if (t != "")
				chrRecipe.add(t);
			t = "";
		}
		
		sr.shape(chrRecipe.toArray(new String[0]));
		Set<String> key = itemRecipe.keySet();
		for (Iterator<String> it = key.iterator(); it.hasNext();) {
			String s = it.next();
			sr.setIngredient(s.toCharArray()[0], Material.getMaterial(itemRecipe.get(s)));
		}
		return sr;

	}

	static void DebugLogger(String m) {
		if (debug)
			consoleLogger.info("[DEBUG] " + m);
	}

	void OutputExcpetion(String from, Exception e) {
		getLogger().info("-> In " + from);
		getLogger().info("->" + e.getMessage());
		getLogger().info("->" + e.toString());
		getLogger().info("->" + e.getLocalizedMessage());
	}

	boolean CreateConfig() {
		try {
			InputStream in = getResource("config.yml");
			OutputStream out = new FileOutputStream(cfg);

			byte[] buffer = new byte[1024];
			int len;
			while ((len = in.read(buffer)) != -1) {
				out.write(buffer, 0, len);
			}
			in.close();
			out.close();
		} catch (Exception e) {
			consoleLogger.info("Can't create config.yml file.");
			return false;
		}
		return true;
	}

	boolean LoadConfig() {
		yamlConfig = new YamlConfiguration();
		try {

			yamlConfig.load(cfg);
			debug = yamlConfig.getBoolean("Config.Debug");
			enablePerm = yamlConfig.getBoolean("Config.EnablePerm");
			itemCount = yamlConfig.getInt("Items.ItemCount");
			DebugLogger("Custom Recipe Count:" + itemCount);
			for (int i = 1; i <= itemCount; i++) {
				DebugLogger("Index:" + i);
				rec.put(i, new RecipeItem(yamlConfig, i));
				DebugLogger("Loading ID " + rec.get(i).getName() + "(" + (rec.get(i).getID()) + ") Recips form file");

				ItemStack is = rec.get(i).getItemStack();

				sr.put(i, GetRecipe(is, rec.get(i).getRepice()));
				DebugLogger("Init ShapedRecipe");
				getServer().addRecipe(sr.get(i));
				DebugLogger("Add to craft recipe");
			}
			consoleLogger.info("Loading Recips complete!");
		} catch (FileNotFoundException e) {
			consoleLogger.info("Config file not found , plugin disabled");
			setEnabled(false);
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			consoleLogger.info("IO Exception catched , please check your harddisk");
			return false;
		} catch (InvalidConfigurationException e) {
			e.printStackTrace();
			consoleLogger.info("Config invalid! Check your config and reload plugin");
			return false;
		}
		return true;
	}

	boolean Reload(CommandSender sender) {
		if (!sender.hasPermission("bakarecipe.reload")) {
			sender.sendMessage("权限不足");
			consoleLogger.info("Player " + sender.getName() + " tried reload plugin!");
			return false;
		} else {
			getServer().resetRecipes();
			sr.clear();
			rec.clear();
			LoadConfig();
			sender.sendMessage("Reload successful.");

			return true;
		}
	}

	@Override
	public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
		if (label.equalsIgnoreCase("brecipce")) {
			if (args[0].equals("reload"))
				return Reload(sender);
			else if (args[0].equals("raise"))
				return Raise(sender, args[1]);
		}
		sender.sendMessage("未知命令" + args[0]);
		return false;
	}

	private boolean Raise(CommandSender sender, String string) {
		if (sender instanceof Player && sender.hasPermission("brecipce.raise")) {
			((Player) sender).getInventory().addItem(rec.get(Integer.parseInt(string)).getItemStack());
		}
		return false;
	}

	@Override
	public void onEnable() {
		consoleLogger = this.getLogger();
		mmMobsInstance = (MythicMobs) Bukkit.getPluginManager().getPlugin("MythicMobs");
		
		//mmMobsInstance.onEnable();
		//enable force
		if (!getDataFolder().exists()) {
			consoleLogger.info("Can't load config file ,please config the plugin after use it.");
			getDataFolder().mkdir();
			CreateConfig();
		}
		cfg = new File(getDataFolder(), "config.yml");
		if (!cfg.exists()) {
			CreateConfig();
			consoleLogger.info("Config loaded fail, copy form jar.");
			setEnabled(false);
			return;
		}
		if (cfg.exists())
			LoadConfig();
		getServer().getPluginManager().registerEvents(this, this);
		consoleLogger.info("BAKARecipce Started Successfuly!!");

	}

	@Override
	public void onDisable() {
		rec.clear();
		consoleLogger.info("BAKARecipce Close Successfuly!!");
	}

	@EventHandler
	public void onCraft(CraftItemEvent event) {
		DebugLogger("Craft Passed");
		DebugLogger(event.getCurrentItem().toString());
		DebugLogger(event.getWhoClicked().getName());
		if (enablePerm) {
			if (event.getRecipe() instanceof ShapedRecipe) {
				ShapedRecipe t = ((ShapedRecipe) event.getRecipe());
				Set<Integer> key = sr.keySet();
				for (Iterator<Integer> it = key.iterator(); it.hasNext();) {
					int s = it.next();
					ShapedRecipe r = sr.get(s);
					if (r.getResult().equals(t.getResult())) {
						if (r.getShape().length == t.getShape().length) {
							boolean isSame = true;
							for (int k = 0; k < r.getShape().length; k++) {
								if (r.getShape()[k].toString().equalsIgnoreCase(t.getShape()[k])) {
									if (t == r) {
										isSame = false;
										break;
									}
									if (isSame == false)
										break;
								}
							}
							if (isSame) {
								DebugLogger(rec.get(s).getPermName());
								if (rec.get(s).getPermName() != null && !rec.get(s).getPermName().equals("")) {
									if (!event.getWhoClicked().hasPermission(rec.get(s).getPermName())) {
										DebugLogger("Leak Perm to craft");
										event.setCancelled(true);
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
